#include "transContentDispatcherThreads.hpp"

TransContentDispatcherThreads* TransContentDispatcherThreads::_instance = NULL;

TransContentDispatcherThreads* TransContentDispatcherThreads::getInstance(){
	if(_instance == NULL){
		_instance = new TransContentDispatcherThreads();
		if(_instance->getState() == INS_STATE_ERROR){
			log_error("create dispatcher threads failed");
			releaseInstance();
		}
		log_info("create dispathcer thread instance sucess");
	}
	return _instance;
}

void TransContentDispatcherThreads::releaseInstance(){
	if(_instance != NULL){
		delete _instance;
		_instance = NULL;
	}
}

TransContentDispatcherThreads::TransContentDispatcherThreads(){
	mState = INS_STATE_ERROR;
	capacity = THREADS_COUNT_DEFAULT;
	log_info("dispatcherThreads constructor");
	if(createThreads() != E_TRANC_SUCESS){
		return ;
	}
	mState = INS_STATE_OK;
}
TransContentDispatcherThreads::~TransContentDispatcherThreads(){
	log_warm("dispatcherThreads destructor");
	closeAllThreads();
	mState = INS_STATE_ERROR;
}

///////////////////////////////////////////////////////////////////
/// create a mount of threads, and run the startRun method
/// after each thread created, detach it
///
/// return:
///		E_TRANC_SystemError: when create thread failed
///		E_TRANC_SUCESS: when create all sucess
///////////////////////////////////////////////////////////////////
int TransContentDispatcherThreads::createThreads(){
	mThreadPool = (pthread_t*)calloc(capacity, sizeof(pthread_t));
	for(mCount=0; mCount< capacity; ++mCount){
		if(pthread_create(&mThreadPool[mCount], NULL, startRun, NULL) != 0){
			logd_fata_error("create thread failed!!");
			return E_TRANC_SystemError;
		}
		pthread_detach(mThreadPool[mCount]);
	}
	return E_TRANC_SUCESS;
}

void TransContentDispatcherThreads::closeAllThreads(){
	for(; mCount>=0 && mThreadPool[mCount] != 0; --mCount){
		pthread_cancel(mThreadPool[mCount]);
	}
}

void* TransContentDispatcherThreads::startRun(void* p){
	TransContentDispatcher* ins = TransContentDispatcher::getInstance();
	if(ins->getState() != INS_STATE_OK){
		logd_error("get dispather instance falied!!");
		return NULL;
	}
	while(1){
		ins->receiveDataFromStack();
	}
}
